import os.path

import numpy as np

from constant import *


def gif_to_surfaces(gif_path):
    gif_frame = Image.open(gif_path)
    frames = [pg.image.fromstring(frame.convert('RGBA').tobytes(), frame.size, 'RGBA')
              for frame in ImageSequence.Iterator(gif_frame)]
    return frames


def gif_to_save(gif_path, save_path=None, suffix: Literal['.png', '.jpg'] = '.png'):
    gif = Image.open(gif_path)
    if save_path is None:
        save_path = gif_path[:-4]
    try:
        os.makedirs(save_path)
        interval = []
        for i, frame in enumerate(ImageSequence.Iterator(gif)):
            interval.append(frame.info['duration'] / 60)
            frame.save(save_path + f'\\{i}{suffix}')
    except FileExistsError:
        interval = []
        for frame in ImageSequence.Iterator(gif):
            interval.append(1000 / frame.info['duration'])
    return interval, save_path


def points_trajectory(point0, point1, pace=10):
    """

    :param point0: x较大者
    :param point1: x较小者
    :param pace: 步长
    :return: 二元列表
    """
    trajectory = [(point0[0] - x, point0[1] - x * (point0[1] - point1[1]) / (point0[0] - point1[0])) for x in range(0, point0[0] - point1[0], pace)]
    return trajectory + [point1]


def image_array(image_path):
    with Image.open(image_path).convert('RGBA') as image:
        image = ImageSequence.Iterator(image)[0]
        return np.array(image)


def create_plant_lists(row_properties: list[Literal['unsuitable', 'grassland', 'pool', 'roof']] = None):
    class Lawn:
        def __init__(self, row_property):
            self.property = row_property
            self.plants = []

        def add(self, plant):
            if plant.property == self.property:
                if len(self.plants) == 0:
                    self.plants.append(plant)
                    return True
                elif len(self.plants) == 1:
                    for p in self.plants:
                        if (p.other_property in ('pack', 'load') or plant.other_property in (
                        'pack', 'load')) and p.other_property != plant.other_property:
                            self.plants.append(plant)
                            return True
                return False
            else:
                return False

        def update(self):
            if self.property == 'snowfield':
                self.plants = []
            else:
                self.plants = [plant for plant in self.plants if not plant.over]
                for plant in self.plants:
                    plant.update()

    if row_properties is None:
        row_properties = ['grassland'] * 5
    plant_grid = []
    for row in row_properties:
        row_of_plants = [Lawn(row) for _ in range(LAWN_COLUMN)]
        plant_grid.append(row_of_plants)
    return plant_grid


def update_plant_array(plant_array):
    for row in plant_array:
        for plant in row:
            plant.update()


def create_zombies_lists(row_properties: list[Literal['unsuitable', 'grassland', 'pool', 'roof']]):
    class Row:
        def __init__(self, row_property):
            self.property = row_property
            self.zombies = []

        def add(self, zombie):
            if zombie.property == self.property or zombie.property == 'flight':
                self.zombies.append(zombie)

        def update(self):
            self.zombies = [zombie for zombie in self.zombies if not zombie.over]
            for zombie in self.zombies:
                zombie.update()

